"""
Grave! Important! Важно!

Proletoj el ĉiuj landoj, unuiĝu!
Workers of the world, unite!
Пролетарии всех стран, соединяйтесь!

https://tkom.pro
"""

from django.http.response import JsonResponse
from django.template.loader import render_to_string
from django.utils.translation import ugettext as _
from django.core.serializers import serialize
import json
import datetime


class SiriusoPaginationMixin:

    ajax_template = None
    mobile_ajax_teplate = None

    page_offset = 0
    page_max = 25

    page_key = 'page'
    page_offset_key = 'offset'
    page_max_key = 'page_max'
    page_multi = None

    is_pagination = False
    is_ajax_pagination = False
    is_multi_pagination = False

    def pagination_dispatch(self, request, *args, **kwargs):
        # Проверяем, является ли данный запрос AJAX подгрузки элементов страницы
        handler = None

        if request.method.lower() == 'post'\
                and (self.page_key in request.POST or
                     self.page_offset_key in request.POST):

            self.is_pagination = True
            self.is_ajax_pagination = True

            if self.page_key in request.POST:
                self.page_offset = int(request.POST.get(self.page_key, 0))*self.page_max
            else:
                self.page_offset = int(request.POST.get(self.page_offset_key, self.page_offset))

            handler = getattr(self, 'page_post', None)

        return handler

    def page_post(self, request, *args, **kwargs):
        response = {'status': 'error', 'err': 'Bad pagination AJAX request'}
        context_handler = getattr(self, 'get_context_data', None)

        if context_handler is not None:
            multi = request.POST.get('page_multi', None)
            multi = self.__parse_multiple(multi)

            if multi is not None:
                self.page_multi = multi
                self.is_multi_pagination = True

            context = context_handler(**kwargs)

            if getattr(self, '_is_mobile', False):
                content = render_to_string(self.mobile_ajax_teplate, context)
            else:
                content = render_to_string(self.ajax_template, context)

            response = {
                'status': 'ok',
                'html': content,
                'more': context.get('more', True),
                'offset': context.get('offset', 0) + self.page_offset
            }

            if self.page_multi is not None:
                response.update({'multi': self.page_multi})
        else:
            response['err'] = "Internal server error: no context data for pagination"

        return JsonResponse(response)

    def multiple_last_objects(self, union_list, fields=None):
        out = {}

        objects = list(reversed(union_list[0:self.page_max]))

        for object in objects:
            if object.__class__.__name__ not in out:
                if fields is None:
                    out[object.__class__.__name__] = serialize('json', [object,])
                else:
                    def microconvert(obj):
                        if isinstance(obj, datetime.datetime):
                            return obj.strftime('%Y-%m-%d %H:%M:%S.%f')
                        elif not isinstance(obj, str):
                            if '__str__' in dir(obj):
                                return obj.__str__()
                        return obj

                    out_dict = {}
                    for field in fields:
                        out_dict[field] = microconvert(getattr(object, field, None))

                    out[object.__class__.__name__] = json.dumps([out_dict])

        return out

    def __parse_multiple(self, json_str):
        # Преобразуем переданные в POST данные о последних объектах
        # в мультиобъектной списковой странице
        multi = json.loads(json_str) if json_str is not None else None

        if multi is not None:
            for cur in multi:
                multi[cur] = json.loads(multi[cur])[0] # ['fields']

        return multi